using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[RequireComponent(typeof(Rigidbody))]
public class RCCCarControllerV2 : MonoBehaviour
{
    public enum MobileGUIType
    {
        UIController,
        NGUIController
    }

    public enum DashboardType
    {
        UIDashboard,
        NGUIDashboard
    }

    public enum WheelType
    {
        FWD,
        RWD,
        AWD,
        DRIFT
    }

    public enum GroundMaterial
    {
        Asphalt,
        Grass,
        Sand
    }

    private struct originalMeshVerts
    {
        public Vector3[] meshVerts;
    }

    private Rigidbody rigid;

    internal bool sleepingRigid;

    public bool mobileController;

    public MobileGUIType _mobileControllerType;

    public bool AIController;

    public bool dashBoard;

    public DashboardType _dashboardType;

    public bool useAccelerometerForSteer;

    public bool steeringWheelControl;

    public float gyroTiltMultiplier = 2f;

    public bool demoGUI;

    public bool showMobileControllerChangerButtons;

    private Vector3 defbrakePedalPosition;

    public bool autoFindButtons = true;

    public RCCNGUIController gasPedalNGUI;

    public RCCNGUIController brakePedalNGUI;

    public RCCNGUIController leftArrowNGUI;

    public RCCNGUIController rightArrowNGUI;

    public RCCNGUIController handbrakeNGUI;

    public RCCNGUIController boostNGUI;

    public RCCUIController gasPedalUI;

    public RCCUIController brakePedalUI;

    public RCCUIController leftArrowUI;

    public RCCUIController rightArrowUI;

    public RCCUIController handbrakeUI;

    public RCCUIController boostUI;

    public Transform FrontLeftWheelTransform;

    public Transform FrontRightWheelTransform;

    public Transform RearLeftWheelTransform;

    public Transform RearRightWheelTransform;

    public WheelCollider FrontLeftWheelCollider;

    public WheelCollider FrontRightWheelCollider;

    public WheelCollider RearLeftWheelCollider;

    public WheelCollider RearRightWheelCollider;

    private WheelCollider[] allWheelColliders;

    private WheelFrictionCurve sidewaysFriction;

    private WheelFrictionCurve forwardFriction;

    public Transform[] ExtraRearWheelsTransform;

    public WheelCollider[] ExtraRearWheelsCollider;

    public bool applyEngineTorqueToExtraRearWheelColliders = true;

    public Transform SteeringWheel;

    public WheelType _wheelTypeChoise = WheelType.RWD;

    public Transform COM;

    public bool canControl = true;

    public bool runEngineAtAwake = true;

    public bool canEngineStall = true;

    public bool engineRunning;

    public bool autoReverse = true;

    public bool automaticGear = true;

    private bool canGoReverseNow;

    public AnimationCurve[] engineTorqueCurve;

    public float[] gearSpeed;

    public float engineTorque = 3000f;

    public float maxEngineRPM = 7000f;

    public float minEngineRPM = 1000f;

    public float steerAngle = 40f;

    public float highspeedsteerAngle = 10f;

    public float highspeedsteerAngleAtspeed = 80f;

    public float antiRoll = 5000f;

    public float downForce = 25f;

    public float speed;

    public float brake = 4000f;

    public float maxspeed = 220f;

    private float resetTime;

    private float defSteerAngle;

    public int currentGear;

    public int totalGears = 6;

    [Range(0f, 0.5f)]
    public float gearShiftingDelay = 0.35f;

    public bool changingGear;

    public bool reverseGear;

    public bool autoGenerateGearCurves = true;

    public bool autoGenerateTargetSpeedsForChangingGear = true;

    private float _rotationValueFL;

    private float _rotationValueFR;

    private float _rotationValueRL;

    private float _rotationValueRR;

    private float[] _rotationValueExtra;

    private float acceleration;

    private float lastVelocity;

    private bool engineStarting;

    private AudioSource engineStartSound;

    public AudioClip engineStartClip;

    private AudioSource engineSoundOn;

    public AudioClip engineClipOn;

    private AudioSource engineSoundOff;

    public AudioClip engineClipOff;

    private AudioSource gearShiftingSound;

    public AudioClip[] gearShiftingClips;

    private AudioSource crashSound;

    public AudioClip[] crashClips;

    private AudioSource windSound;

    public AudioClip windClip;

    private AudioSource brakeSound;

    public AudioClip brakeClip;

    private AudioSource skidSound;

    public AudioClip asphaltSkidClip;

    public AudioClip grassSkidClip;

    public AudioClip sandSkidClip;

    [Range(0.25f, 1f)]
    public float minEngineSoundPitch = 0.75f;

    [Range(1.25f, 2f)]
    public float maxEngineSoundPitch = 1.75f;

    [Range(0f, 1f)]
    public float minEngineSoundVolume = 0.05f;

    [Range(0f, 1f)]
    public float maxEngineSoundVolume = 0.85f;

    [Range(0f, 1f)]
    public float maxGearShiftingSoundVolume = 0.3f;

    [Range(0f, 1f)]
    public float maxSkidSoundVolume = 1f;

    [Range(0f, 1f)]
    public float maxCrashSoundVolume = 1f;

    [Range(0f, 1f)]
    public float maxWindSoundVolume = 0.25f;

    [Range(0f, 1f)]
    public float maxBrakeSoundVolume = 0.2f;

    private GameObject allAudioSources;

    private GameObject allContactParticles;

    public PhysicMaterial asphaltPhysicsMaterial;

    public PhysicMaterial grassPhysicsMaterial;

    public PhysicMaterial sandPhysicsMaterial;

    public PhysicMaterial terrainPhysicsMaterial;

    public bool UseTerrainSplatMapForGroundPhysics;

    public int terrainSplatMapAsphaltIndex;

    public int terrainSplatMapGrassIndex;

    public int terrainSplatMapSandIndex;

    [HideInInspector]
    public float gasInput;

    [HideInInspector]
    public float brakeInput;

    [HideInInspector]
    public float steerInput;

    [HideInInspector]
    public float clutchInput;

    [HideInInspector]
    public float handbrakeInput;

    [HideInInspector]
    public float fuelInput = 1f;

    [HideInInspector]
    public float boostInput = 1f;

    private float engineRPM;

    private float wheelRPMToSpeed;

    public RCCDashboardInputs UIInputs;

    private RectTransform RPMNeedle;

    private RectTransform KMHNeedle;

    public GameObject RPMNeedleNGUI;

    public GameObject KMHNeedleNGUI;

    private float RPMNeedleRotation;

    private float KMHNeedleRotation;

    private float smoothedNeedleRotation;

    public GroundMaterial _groundMaterial;

    public GameObject wheelSlipAsphalt;

    public GameObject wheelSlipSand;

    private List<ParticleSystem> _wheelSlipAsphalt = new List<ParticleSystem>();

    private List<ParticleSystem> _wheelSlipSand = new List<ParticleSystem>();

    public ParticleSystem[] exhaustGas;

    public GameObject chassis;

    public float chassisVerticalLean = 4f;

    public float chassisHorizontalLean = 4f;

    private float horizontalLean;

    private float verticalLean;

    public Light[] headLights;

    public Light[] brakeLights;

    public Light[] reverseLights;

    public bool headLightsOn;

    private float brakeLightInput;

    public bool useDamage = true;

    public MeshFilter[] deformableMeshFilters;

    public float randomizeVertices = 1f;

    public float damageRadius = 0.5f;

    private float minimumVertDistanceForDamagedMesh = 0.002f;

    private Vector3[] colliderVerts;

    private originalMeshVerts[] originalMeshData;

    [HideInInspector]
    public bool sleep = true;

    public float maximumDamage = 0.5f;

    private float minimumCollisionForce = 5f;

    public float damageMultiplier = 1f;

    public GameObject contactSparkle;

    public int maximumContactSparkle = 5;

    private List<ParticleSystem> contactSparkeList = new List<ParticleSystem>();

    public bool repairNow;

    private Vector3 localVector;

    private Quaternion rot = Quaternion.identity;

    [Range(0f, 1f)]
    public float steerHelper = 0.1f;

    private float oldRotation;

    public bool ABS = true;

    public bool TCS = true;

    public bool ESP = true;

    public bool steeringHelper = true;

    public bool ABSAct;

    public bool TCSAct;

    public bool ESPAct;

    [Range(0.05f, 0.5f)]
    public float ABSThreshold = 0.35f;

    [Range(0.05f, 0.5f)]
    public float TCSThreshold = 0.25f;

    [Range(0f, 1f)]
    public float TCSStrength = 1f;

    [Range(0.05f, 0.5f)]
    public float ESPThreshold = 0.25f;

    [Range(0.1f, 1f)]
    public float ESPStrength = 0.5f;

    internal float driftAngle;

    private bool driftingNow;

    public bool applyCounterSteering;

    public GameObject steeringWheelGameObject;

    public Image steeringWheelTexture;

    public float steeringWheelAngle;

    public float steeringWheelMaximumsteerAngle = 270f;

    public float steeringWheelResetPosSpeed = 10f;

    public float steeringWheelCenterDeadZoneRadius = 5f;

    public float steeringWheelDefaultAlpha = 0.5f;

    public float steeringWheelActiveAlpha = 1f;

    public bool steeringWheelInteractable = true;

    private RectTransform steeringWheelRect;

    private CanvasGroup steeringWheelCanvasGroup;

    private float steeringWheelTempAngle;

    private float steeringWheelNewAngle;

    private bool steeringWheelPressed;

    private Vector2 steeringWheelCenter;

    private Vector2 steeringWheelTouchPos;

    private EventTrigger eventTrigger;

    public bool tireBurn;

    private void Awake()
    {
        if (!GetComponent<RCCAICarController>())
        {
            AIController = false;
        }
    }

    private void Start()
    {
        rigid = GetComponent<Rigidbody>();
        rigid.maxAngularVelocity = 12f;
        Time.fixedDeltaTime = 0.02f;
        allWheelColliders = GetComponentsInChildren<WheelCollider>();
        WheelCollider componentInChildren = GetComponentInChildren<WheelCollider>();
        componentInChildren.ConfigureVehicleSubsteps(30f, 20, 20);
        _rotationValueExtra = new float[ExtraRearWheelsCollider.Length];
        defSteerAngle = steerAngle;
        allAudioSources = new GameObject("All Audio Sources");
        allAudioSources.transform.SetParent(base.transform);
        allAudioSources.transform.localPosition = Vector3.zero;
        allAudioSources.transform.localRotation = Quaternion.identity;
        allContactParticles = new GameObject("All Contact Particles");
        allContactParticles.transform.SetParent(base.transform);
        allContactParticles.transform.localPosition = Vector3.zero;
        allContactParticles.transform.localRotation = Quaternion.identity;
        if (dashBoard && (bool)UnityEngine.Object.FindObjectOfType<RCCDashboardInputs>())
        {
            UIInputs = UnityEngine.Object.FindObjectOfType<RCCDashboardInputs>();
            UIInputs.GetNeedles();
            if (_dashboardType == DashboardType.NGUIDashboard)
            {
                RPMNeedleNGUI = UIInputs.RPMNeedleNGUI;
                KMHNeedleNGUI = UIInputs.KMHNeedleNGUI;
            }
            else
            {
                RPMNeedle = UIInputs.RPMNeedleUI;
                KMHNeedle = UIInputs.KMHNeedleUI;
            }
        }
        else if (dashBoard)
        {
            UnityEngine.Debug.LogError("RCCDashboardInputs not found! Ensure your scene has UI or NGUI canvas with RCCDashboardInputs script. You can use ready to use prefabs in Prefabs folder.");
            dashBoard = false;
        }
        if (autoFindButtons && mobileController)
        {
            RCCMobileButtons rCCMobileButtons = UnityEngine.Object.FindObjectOfType<RCCMobileButtons>();
            if (_mobileControllerType == MobileGUIType.NGUIController)
            {
                gasPedalNGUI = rCCMobileButtons.gasButton.GetComponent<RCCNGUIController>();
                brakePedalNGUI = rCCMobileButtons.brakeButton.GetComponent<RCCNGUIController>();
                leftArrowNGUI = rCCMobileButtons.leftButton.GetComponent<RCCNGUIController>();
                rightArrowNGUI = rCCMobileButtons.rightButton.GetComponent<RCCNGUIController>();
                if ((bool)rCCMobileButtons.handbrakeButton)
                {
                    handbrakeNGUI = rCCMobileButtons.handbrakeButton.GetComponent<RCCNGUIController>();
                }
                if ((bool)rCCMobileButtons.boostButton)
                {
                    boostNGUI = rCCMobileButtons.boostButton.GetComponent<RCCNGUIController>();
                }
            }
            else
            {
                gasPedalUI = rCCMobileButtons.gasButton.GetComponent<RCCUIController>();
                brakePedalUI = rCCMobileButtons.brakeButton.GetComponent<RCCUIController>();
                leftArrowUI = rCCMobileButtons.leftButton.GetComponent<RCCUIController>();
                rightArrowUI = rCCMobileButtons.rightButton.GetComponent<RCCUIController>();
                if ((bool)rCCMobileButtons.handbrakeButton)
                {
                    handbrakeUI = rCCMobileButtons.handbrakeButton.GetComponent<RCCUIController>();
                }
                if ((bool)rCCMobileButtons.boostButton)
                {
                    boostUI = rCCMobileButtons.boostButton.GetComponent<RCCUIController>();
                }
            }
            if ((bool)rCCMobileButtons.steeringWheel)
            {
                steeringWheelTexture = rCCMobileButtons.steeringWheel.GetComponent<Image>();
            }
        }
        SoundsInitialize();
        MobileGUI();
        SmokeInit();
        if (useDamage)
        {
            DamageInit();
        }
        if (runEngineAtAwake)
        {
            KillOrStartEngine();
        }
    }

    public void CreateWheelColliders()
    {
        List<Transform> list = new List<Transform>();
        list.Add(FrontLeftWheelTransform);
        list.Add(FrontRightWheelTransform);
        list.Add(RearLeftWheelTransform);
        list.Add(RearRightWheelTransform);
        if (list[0] == null)
        {
            UnityEngine.Debug.LogError("You haven't choose your Wheel Transforms. Please select all of your Wheel Transforms before creating Wheel Colliders. Script needs to know their positions, aye?");
            return;
        }
        base.transform.rotation = Quaternion.identity;
        GameObject gameObject = new GameObject("Wheel Colliders");
        gameObject.transform.SetParent(base.transform);
        gameObject.transform.localRotation = Quaternion.identity;
        gameObject.transform.localPosition = Vector3.zero;
        gameObject.transform.localScale = Vector3.one;
        foreach (Transform item in list)
        {
            GameObject gameObject2 = new GameObject(item.transform.name);
            gameObject2.transform.position = item.transform.position;
            gameObject2.transform.rotation = base.transform.rotation;
            gameObject2.transform.name = item.transform.name;
            gameObject2.transform.SetParent(gameObject.transform);
            gameObject2.transform.localScale = Vector3.one;
            gameObject2.AddComponent<WheelCollider>();
            WheelCollider component = gameObject2.GetComponent<WheelCollider>();
            Vector3 extents = item.GetComponent<MeshRenderer>().bounds.extents;
            float y = extents.y;
            Vector3 localScale = base.transform.localScale;
            component.radius = y / localScale.y;
            gameObject2.AddComponent<RCCWheelCollider>();
            JointSpring suspensionSpring = gameObject2.GetComponent<WheelCollider>().suspensionSpring;
            suspensionSpring.spring = 35000f;
            suspensionSpring.damper = 1500f;
            gameObject2.GetComponent<WheelCollider>().suspensionSpring = suspensionSpring;
            gameObject2.GetComponent<WheelCollider>().suspensionDistance = 0.2f;
            gameObject2.GetComponent<WheelCollider>().forceAppPointDistance = 0.15f;
            gameObject2.GetComponent<WheelCollider>().mass = 125f;
            gameObject2.GetComponent<WheelCollider>().wheelDampingRate = 1f;
            sidewaysFriction = gameObject2.GetComponent<WheelCollider>().sidewaysFriction;
            forwardFriction = gameObject2.GetComponent<WheelCollider>().forwardFriction;
            forwardFriction.extremumSlip = 0.4f;
            forwardFriction.extremumValue = 1f;
            forwardFriction.asymptoteSlip = 0.8f;
            forwardFriction.asymptoteValue = 0.75f;
            forwardFriction.stiffness = 1f;
            sidewaysFriction.extremumSlip = 0.25f;
            sidewaysFriction.extremumValue = 1f;
            sidewaysFriction.asymptoteSlip = 0.5f;
            sidewaysFriction.asymptoteValue = 0.75f;
            sidewaysFriction.stiffness = 1f;
            gameObject2.GetComponent<WheelCollider>().sidewaysFriction = sidewaysFriction;
            gameObject2.GetComponent<WheelCollider>().forwardFriction = forwardFriction;
        }
        WheelCollider[] array = new WheelCollider[list.Count];
        array = GetComponentsInChildren<WheelCollider>();
        FrontLeftWheelCollider = array[0];
        FrontRightWheelCollider = array[1];
        RearLeftWheelCollider = array[2];
        RearRightWheelCollider = array[3];
    }

    public void SoundsInitialize()
    {
        engineSoundOn = RCCCreateAudioSource.NewAudioSource(base.gameObject, "Engine Sound On AudioSource", 5f, 100f, 0f, engineClipOn, loop: true, playNow: true, destroyAfterFinished: false);
        engineSoundOff = RCCCreateAudioSource.NewAudioSource(base.gameObject, "Engine Sound Off AudioSource", 5f, 100f, 0f, engineClipOff, loop: true, playNow: true, destroyAfterFinished: false);
        windSound = RCCCreateAudioSource.NewAudioSource(base.gameObject, "Wind Sound AudioSource", 5f, 10f, 0f, windClip, loop: true, playNow: true, destroyAfterFinished: false);
        brakeSound = RCCCreateAudioSource.NewAudioSource(base.gameObject, "Brake Sound AudioSource", 5f, 10f, 0f, brakeClip, loop: true, playNow: true, destroyAfterFinished: false);
        skidSound = RCCCreateAudioSource.NewAudioSource(base.gameObject, "Skid Sound AudioSource", 5f, 50f, 0f, asphaltSkidClip, loop: true, playNow: false, destroyAfterFinished: false);
    }

    public void KillOrStartEngine()
    {
        if (engineRunning && !engineStarting)
        {
            engineRunning = false;
        }
        else if (!engineStarting)
        {
            StartCoroutine("StartEngine");
        }
    }

    public IEnumerator StartEngine()
    {
        engineRunning = false;
        engineStarting = true;
        if (!engineRunning)
        {
            engineStartSound = RCCCreateAudioSource.NewAudioSource(base.gameObject, "Engine Start AudioSource", 5f, 10f, 1f, engineStartClip, loop: false, playNow: true, destroyAfterFinished: true);
        }
        yield return new WaitForSeconds(1f);
        engineRunning = true;
        yield return new WaitForSeconds(1f);
        engineStarting = false;
    }

    public void SmokeInit()
    {
        if ((bool)wheelSlipAsphalt)
        {
            for (int i = 0; i < allWheelColliders.Length; i++)
            {
                GameObject gameObject = (GameObject)UnityEngine.Object.Instantiate(wheelSlipAsphalt, base.transform.position, base.transform.rotation);
                _wheelSlipAsphalt.Add(gameObject.GetComponent<ParticleSystem>());
                gameObject.GetComponent<ParticleSystem>().enableEmission = false;
                gameObject.transform.SetParent(allWheelColliders[i].transform);
                gameObject.transform.localPosition = Vector3.zero;
            }
        }
        if ((bool)wheelSlipSand)
        {
            for (int j = 0; j < allWheelColliders.Length; j++)
            {
                GameObject gameObject2 = (GameObject)UnityEngine.Object.Instantiate(wheelSlipSand, base.transform.position, base.transform.rotation);
                _wheelSlipSand.Add(gameObject2.GetComponent<ParticleSystem>());
                gameObject2.GetComponent<ParticleSystem>().enableEmission = false;
                gameObject2.transform.SetParent(allWheelColliders[j].transform);
                gameObject2.transform.localPosition = Vector3.zero;
            }
        }
    }

    public void DamageInit()
    {
        if (deformableMeshFilters.Length == 0)
        {
            MeshFilter[] componentsInChildren = GetComponentsInChildren<MeshFilter>();
            List<MeshFilter> list = new List<MeshFilter>();
            MeshFilter[] array = componentsInChildren;
            foreach (MeshFilter meshFilter in array)
            {
                if (meshFilter.gameObject != FrontLeftWheelTransform.gameObject && meshFilter.gameObject != FrontRightWheelTransform.gameObject && meshFilter.gameObject != RearLeftWheelTransform.gameObject && meshFilter.gameObject != RearRightWheelTransform.gameObject)
                {
                    list.Add(meshFilter);
                }
            }
            deformableMeshFilters = list.ToArray();
        }
        LoadOriginalMeshData();
        if ((bool)contactSparkle)
        {
            for (int j = 0; j < maximumContactSparkle; j++)
            {
                GameObject gameObject = (GameObject)UnityEngine.Object.Instantiate(contactSparkle, base.transform.position, Quaternion.identity);
                gameObject.transform.SetParent(allContactParticles.transform);
                contactSparkeList.Add(gameObject.GetComponent<ParticleSystem>());
                gameObject.GetComponent<ParticleSystem>().enableEmission = false;
            }
        }
    }

    private void SteeringWheelInit()
    {
        steeringWheelGameObject = steeringWheelTexture.gameObject;
        steeringWheelRect = steeringWheelTexture.rectTransform;
        steeringWheelCanvasGroup = steeringWheelTexture.GetComponent<CanvasGroup>();
        steeringWheelCenter = steeringWheelRect.position;
        steeringWheelCanvasGroup.alpha = steeringWheelDefaultAlpha;
        SteeringWheelEventsInit();
    }

    private void LoadOriginalMeshData()
    {
        originalMeshData = new originalMeshVerts[deformableMeshFilters.Length];
        for (int i = 0; i < deformableMeshFilters.Length; i++)
        {
            originalMeshData[i].meshVerts = deformableMeshFilters[i].mesh.vertices;
        }
    }

    private void Damage()
    {
        if (sleep || !repairNow)
        {
            return;
        }
        sleep = true;
        for (int i = 0; i < deformableMeshFilters.Length; i++)
        {
            Vector3[] vertices = deformableMeshFilters[i].mesh.vertices;
            if (originalMeshData == null)
            {
                LoadOriginalMeshData();
            }
            for (int j = 0; j < vertices.Length; j++)
            {
                vertices[j] += (originalMeshData[i].meshVerts[j] - vertices[j]) * (Time.deltaTime * 2f);
                if ((originalMeshData[i].meshVerts[j] - vertices[j]).magnitude >= minimumVertDistanceForDamagedMesh)
                {
                    sleep = false;
                }
            }
            deformableMeshFilters[i].mesh.vertices = vertices;
            deformableMeshFilters[i].mesh.RecalculateNormals();
            deformableMeshFilters[i].mesh.RecalculateBounds();
        }
        if (sleep)
        {
            repairNow = false;
        }
    }

    private void DeformMesh(Mesh mesh, Vector3[] originalMesh, Collision collision, float cos, Transform meshTransform, Quaternion rot)
    {
        Vector3[] vertices = mesh.vertices;
        ContactPoint[] contacts = collision.contacts;
        for (int i = 0; i < contacts.Length; i++)
        {
            ContactPoint contactPoint = contacts[i];
            Vector3 a = meshTransform.InverseTransformPoint(contactPoint.point);
            for (int j = 0; j < vertices.Length; j++)
            {
                if ((a - vertices[j]).magnitude < damageRadius)
                {
                    vertices[j] += rot * (localVector * (damageRadius - (a - vertices[j]).magnitude) / damageRadius * cos + UnityEngine.Random.onUnitSphere * (randomizeVertices / 500f));
                    if (maximumDamage > 0f && (vertices[j] - originalMesh[j]).magnitude > maximumDamage)
                    {
                        vertices[j] = originalMesh[j] + (vertices[j] - originalMesh[j]).normalized * maximumDamage;
                    }
                }
            }
        }
        mesh.vertices = vertices;
        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
    }

    private void CollisionParticles(Vector3 contactPoint)
    {
        for (int i = 0; i < contactSparkeList.Count && !contactSparkeList[i].isPlaying; i++)
        {
            contactSparkeList[i].transform.position = contactPoint;
            contactSparkeList[i].enableEmission = true;
            contactSparkeList[i].Play();
        }
    }

    public void MobileGUI()
    {
        if (mobileController)
        {
            if (_mobileControllerType == MobileGUIType.NGUIController)
            {
                defbrakePedalPosition = brakePedalNGUI.transform.position;
            }
            else
            {
                defbrakePedalPosition = brakePedalUI.transform.position;
            }
        }
    }

    private void Update()
    {
        if (canControl)
        {
            Lights();
            ResetCar();
            if (!AIController && !mobileController)
            {
                KeyboardControlling();
            }
            if (steeringWheelControl && !steeringWheelRect && (bool)steeringWheelTexture)
            {
                SteeringWheelInit();
            }
        }
        else if (!AIController)
        {
            gasInput = 0f;
            brakeInput = 0f;
            boostInput = 1f;
            handbrakeInput = 1f;
        }
        GearBox();
        if (!sleepingRigid)
        {
            WheelAlign(FrontLeftWheelCollider, FrontLeftWheelTransform, _rotationValueFL);
            WheelAlign(FrontRightWheelCollider, FrontRightWheelTransform, _rotationValueFR);
            WheelAlign(RearLeftWheelCollider, RearLeftWheelTransform, _rotationValueRL);
            WheelAlign(RearRightWheelCollider, RearRightWheelTransform, _rotationValueRR);
            _rotationValueFL = WheelRotation(FrontLeftWheelCollider, _rotationValueFL);
            _rotationValueFR = WheelRotation(FrontRightWheelCollider, _rotationValueFR);
            _rotationValueRL = WheelRotation(RearLeftWheelCollider, _rotationValueRL);
            _rotationValueRR = WheelRotation(RearRightWheelCollider, _rotationValueRR);
            if (ExtraRearWheelsCollider.Length > 0)
            {
                for (int i = 0; i < ExtraRearWheelsCollider.Length; i++)
                {
                    WheelAlign(ExtraRearWheelsCollider[i], ExtraRearWheelsTransform[i], _rotationValueExtra[i]);
                    _rotationValueExtra[i] = WheelRotation(ExtraRearWheelsCollider[i], _rotationValueExtra[i]);
                }
            }
            for (int j = 0; j < allWheelColliders.Length; j++)
            {
                WheelCamber(allWheelColliders[j]);
            }
        }
        GroundPhysicsMaterial();
        Sounds();
        if (useDamage)
        {
            Damage();
        }
        if ((bool)chassis)
        {
            Chassis();
        }
        if (dashBoard && canControl)
        {
            Dashboard();
        }
    }

    private void FixedUpdate()
    {
        if (canControl)
        {
            if (mobileController && !AIController)
            {
                if (_mobileControllerType == MobileGUIType.NGUIController)
                {
                    NGUIControlling();
                }
                if (_mobileControllerType == MobileGUIType.UIController)
                {
                    UIControlling();
                }
                MobileSteeringInputs();
            }
            SteeringWheelControlling();
        }
        Engine();
        Braking();
        AntiRollBars();
        DownForce();
        DriftVariables();
        SmokeWeedEveryday(_groundMaterial);
        ApplySteering(FrontLeftWheelCollider);
        ApplySteering(FrontRightWheelCollider);
        if (steeringHelper)
        {
            SteerHelper();
        }
        if (ESP)
        {
            Vector3 vector = base.transform.TransformDirection(rigid.angularVelocity);
            if (vector.y > 0f)
            {
                ESPCheck(FrontLeftWheelCollider, FrontRightWheelCollider, RearLeftWheelCollider);
                ESPCheck(RearLeftWheelCollider, RearRightWheelCollider, FrontLeftWheelCollider);
            }
            Vector3 vector2 = base.transform.TransformDirection(rigid.angularVelocity);
            if (vector2.y < 0f)
            {
                ESPCheck(FrontLeftWheelCollider, FrontRightWheelCollider, RearRightWheelCollider);
                ESPCheck(RearLeftWheelCollider, RearRightWheelCollider, FrontRightWheelCollider);
            }
        }
    }

    public void Engine()
    {
        speed = rigid.velocity.magnitude * 3.6f;
        acceleration = 0f;
        Vector3 vector = base.transform.InverseTransformDirection(rigid.velocity);
        acceleration = (vector.z - lastVelocity) / Time.fixedDeltaTime;
        Vector3 vector2 = base.transform.InverseTransformDirection(rigid.velocity);
        lastVelocity = vector2.z;
        rigid.drag = Mathf.Clamp(acceleration / 50f, 0.05f, 0.1f);
        rigid.angularDrag = Mathf.Clamp(speed / maxspeed, 0.05f, 0.25f);
        steerAngle = Mathf.Lerp(defSteerAngle, highspeedsteerAngle, speed / highspeedsteerAngleAtspeed);
        if ((bool)SteeringWheel)
        {
            SteeringWheel.transform.rotation = base.transform.rotation * Quaternion.Euler(20f, 0f, FrontLeftWheelCollider.steerAngle * -6f);
        }
        if (rigid.velocity.magnitude < 0.01f && Mathf.Abs(steerInput) < 0.01f && Mathf.Abs(gasInput) < 0.01f)
        {
            Vector3 angularVelocity = rigid.angularVelocity;
            if (Mathf.Abs(angularVelocity.x) < 0.01f)
            {
                sleepingRigid = true;
                goto IL_01c1;
            }
        }
        sleepingRigid = false;
        goto IL_01c1;
    IL_01c1:
        float num = 0f;
        WheelHit hit;
        if (_wheelTypeChoise == WheelType.RWD || _wheelTypeChoise == WheelType.AWD || _wheelTypeChoise == WheelType.DRIFT)
        {
            RearLeftWheelCollider.GetGroundHit(out hit);
            wheelRPMToSpeed = Mathf.Abs(RearLeftWheelCollider.rpm * RearLeftWheelCollider.radius + RearRightWheelCollider.rpm * RearRightWheelCollider.radius) / 2f / 2.625f;
        }
        if (_wheelTypeChoise == WheelType.FWD)
        {
            FrontLeftWheelCollider.GetGroundHit(out hit);
            wheelRPMToSpeed = Mathf.Abs(FrontLeftWheelCollider.rpm * FrontLeftWheelCollider.radius + FrontRightWheelCollider.rpm * FrontRightWheelCollider.radius) / 2f / 2.625f;
        }
        engineRPM = Mathf.Lerp(b: (((!reverseGear) ? Mathf.Clamp(Mathf.Lerp(minEngineRPM, maxEngineRPM, (wheelRPMToSpeed - ((currentGear == 0) ? 0f : gearSpeed[currentGear - 1])) / (gearSpeed[currentGear] * 1f)) * (1f - clutchInput) + clutchInput * gasInput * maxEngineRPM, minEngineRPM, maxEngineRPM) : ((!automaticGear) ? Mathf.Clamp(Mathf.Lerp(minEngineRPM, maxEngineRPM, wheelRPMToSpeed / (gearSpeed[currentGear] * 2f)) * (1f - clutchInput) + clutchInput * gasInput * maxEngineRPM, minEngineRPM, maxEngineRPM) : Mathf.Clamp(Mathf.Lerp(minEngineRPM, maxEngineRPM, wheelRPMToSpeed / (gearSpeed[currentGear] * 2f)) * (1f - clutchInput) + clutchInput * brakeInput * maxEngineRPM, minEngineRPM, maxEngineRPM))) + UnityEngine.Random.Range(-50f, 50f)) * fuelInput, a: engineRPM, t: Time.deltaTime * 2f);
        if (engineRPM < minEngineRPM / 2f && !engineStarting && canEngineStall)
        {
            engineRunning = false;
        }
        if (!engineRunning)
        {
            fuelInput = 0f;
        }
        else
        {
            fuelInput = 1f;
        }
        if (autoReverse)
        {
            canGoReverseNow = true;
        }
        else if (brakeInput < 0.1f && speed < 5f)
        {
            canGoReverseNow = true;
        }
        else if (brakeInput > 0f)
        {
            Vector3 vector3 = base.transform.InverseTransformDirection(rigid.velocity);
            if (vector3.z > 1f)
            {
                canGoReverseNow = false;
            }
        }
        for (int i = 0; i < allWheelColliders.Length; i++)
        {
            allWheelColliders[i].wheelDampingRate = Mathf.Lerp(2f, 0f, gasInput);
        }
        switch (_wheelTypeChoise)
        {
            case WheelType.FWD:
                ApplyMotorTorque(FrontLeftWheelCollider, engineTorque);
                ApplyMotorTorque(FrontRightWheelCollider, engineTorque);
                break;
            case WheelType.RWD:
                ApplyMotorTorque(RearLeftWheelCollider, engineTorque);
                ApplyMotorTorque(RearRightWheelCollider, engineTorque);
                break;
            case WheelType.AWD:
                ApplyMotorTorque(FrontLeftWheelCollider, engineTorque / 2f);
                ApplyMotorTorque(FrontRightWheelCollider, engineTorque / 2f);
                ApplyMotorTorque(RearLeftWheelCollider, engineTorque / 2f);
                ApplyMotorTorque(RearRightWheelCollider, engineTorque / 2f);
                break;
            case WheelType.DRIFT:
                ApplyMotorTorque(FrontLeftWheelCollider, engineTorque * 30f / 100f);
                ApplyMotorTorque(FrontRightWheelCollider, engineTorque * 30f / 100f);
                ApplyMotorTorque(RearLeftWheelCollider, engineTorque * 70f / 100f);
                ApplyMotorTorque(RearRightWheelCollider, engineTorque * 70f / 100f);
                break;
        }
        if (ExtraRearWheelsCollider.Length > 0 && applyEngineTorqueToExtraRearWheelColliders)
        {
            for (int j = 0; j < ExtraRearWheelsCollider.Length; j++)
            {
                ApplyMotorTorque(ExtraRearWheelsCollider[j], engineTorque);
            }
        }
    }

    public void Sounds()
    {
        windSound.volume = Mathf.Lerp(0f, maxWindSoundVolume, speed / maxspeed);
        windSound.pitch = UnityEngine.Random.Range(0.9f, 1.1f);
        if (!reverseGear)
        {
            brakeSound.volume = Mathf.Lerp(0f, maxBrakeSoundVolume, Mathf.Clamp01((FrontLeftWheelCollider.brakeTorque + FrontRightWheelCollider.brakeTorque) / (brake * 2f)) * Mathf.Lerp(0f, 1f, FrontLeftWheelCollider.rpm / 50f));
        }
        else
        {
            brakeSound.volume = 0f;
        }
    }

    public void ApplyMotorTorque(WheelCollider wc, float torque)
    {
        if (TCS)
        {
            wc.GetGroundHit(out WheelHit hit);
            if (Mathf.Abs(wc.rpm) >= 100f)
            {
                if (hit.forwardSlip > 0.25f)
                {
                    TCSAct = true;
                    torque -= Mathf.Clamp(torque * hit.forwardSlip * TCSStrength, 0f, engineTorque);
                }
                else
                {
                    TCSAct = false;
                    torque += Mathf.Clamp(torque * hit.forwardSlip * TCSStrength, 0f - engineTorque, 0f);
                }
            }
            else
            {
                TCSAct = false;
            }
        }
        if (OverTorque())
        {
            torque = 0f;
        }
        if (automaticGear)
        {
            if (!reverseGear)
            {
                wc.motorTorque = torque * (1f - clutchInput) * (Mathf.Clamp(gasInput * fuelInput, 0f, 1f) * boostInput) * engineTorqueCurve[currentGear].Evaluate(wheelRPMToSpeed);
            }
            else
            {
                wc.motorTorque = (0f - torque) * (1f - clutchInput) * (Mathf.Clamp(brakeInput * fuelInput, 0f, 1f) * boostInput) * engineTorqueCurve[currentGear].Evaluate(wheelRPMToSpeed);
            }
        }
        else if (!reverseGear)
        {
            wc.motorTorque = torque * (1f - clutchInput) * (Mathf.Clamp(gasInput * fuelInput, 0f, 1f) * boostInput) * engineTorqueCurve[currentGear].Evaluate(wheelRPMToSpeed);
        }
        else
        {
            wc.motorTorque = (0f - torque) * (1f - clutchInput) * (Mathf.Clamp(gasInput * fuelInput, 0f, 1f) * boostInput) * engineTorqueCurve[currentGear].Evaluate(wheelRPMToSpeed);
        }
        ApplyEngineSound(wc.motorTorque);
    }

    public void ESPCheck(WheelCollider slippingLeftWheel, WheelCollider slippingRightWheel, WheelCollider correspondingWheel)
    {
        slippingLeftWheel.GetGroundHit(out WheelHit hit);
        slippingRightWheel.GetGroundHit(out WheelHit hit2);
        float num = Mathf.Abs(hit.sidewaysSlip) + Mathf.Abs(hit2.sidewaysSlip);
        if (num > ESPThreshold)
        {
            ESPAct = true;
            ApplyBrakeTorque(correspondingWheel, brake * ESPStrength * num);
        }
        else
        {
            ESPAct = false;
        }
    }

    public void ApplyBrakeTorque(WheelCollider wc, float brake)
    {
        if (ABS && handbrakeInput <= 0.1f)
        {
            wc.GetGroundHit(out WheelHit hit);
            if (Mathf.Abs(hit.forwardSlip) * brakeInput >= ABSThreshold)
            {
                ABSAct = true;
                brake = 0f;
            }
            else
            {
                ABSAct = false;
            }
        }
        wc.brakeTorque = brake;
    }

    public void ApplySteering(WheelCollider wc)
    {
        if (!applyCounterSteering)
        {
            wc.steerAngle = Mathf.Clamp(steerAngle * steerInput, 0f - steerAngle, steerAngle);
        }
        else
        {
            wc.steerAngle = Mathf.Clamp(steerAngle * (steerInput + driftAngle), 0f - steerAngle, steerAngle);
        }
    }

    public void ApplyEngineSound(float input)
    {
        if ((bool)engineSoundOn)
        {
            if (automaticGear)
            {
                if (!reverseGear)
                {
                    engineSoundOn.volume = Mathf.Lerp(engineSoundOn.volume, Mathf.Clamp(gasInput, minEngineSoundVolume * fuelInput, maxEngineSoundVolume), Time.deltaTime * 50f);
                }
                else
                {
                    engineSoundOn.volume = Mathf.Lerp(engineSoundOn.volume, Mathf.Clamp(brakeInput, minEngineSoundVolume * fuelInput, maxEngineSoundVolume), Time.deltaTime * 50f);
                }
            }
            else
            {
                engineSoundOn.volume = Mathf.Lerp(engineSoundOn.volume, Mathf.Clamp(gasInput, minEngineSoundVolume * fuelInput, maxEngineSoundVolume), Time.deltaTime * 50f);
            }
            if (engineRunning)
            {
                engineSoundOn.pitch = Mathf.Lerp(engineSoundOn.pitch, Mathf.Lerp(minEngineSoundPitch * fuelInput, maxEngineSoundPitch, engineRPM / maxEngineRPM), Time.deltaTime * 50f);
            }
            else
            {
                engineSoundOn.pitch = Mathf.Lerp(engineSoundOn.pitch, 0f, Time.deltaTime * 50f);
            }
        }
        if (!engineSoundOff)
        {
            return;
        }
        if (automaticGear)
        {
            if (!reverseGear)
            {
                engineSoundOff.volume = Mathf.Lerp(engineSoundOff.volume, Mathf.Clamp((1f + (0f - gasInput)) * fuelInput, minEngineSoundVolume * fuelInput, 0.5f), Time.deltaTime * 50f);
            }
            else
            {
                engineSoundOff.volume = Mathf.Lerp(engineSoundOff.volume, Mathf.Clamp((1f + (0f - brakeInput)) * fuelInput, minEngineSoundVolume * fuelInput, 0.5f), Time.deltaTime * 50f);
            }
        }
        else
        {
            engineSoundOff.volume = Mathf.Lerp(engineSoundOff.volume, Mathf.Clamp((1f + gasInput) * fuelInput, minEngineSoundVolume * fuelInput, 0.5f), Time.deltaTime * 50f);
        }
        if (engineRunning)
        {
            engineSoundOff.pitch = Mathf.Lerp(engineSoundOff.pitch, Mathf.Lerp(minEngineSoundPitch * fuelInput, maxEngineSoundPitch, engineRPM / maxEngineRPM), Time.deltaTime * 50f);
        }
        else
        {
            engineSoundOff.pitch = Mathf.Lerp(engineSoundOff.pitch, 0f, Time.deltaTime * 50f);
        }
    }

    public void Braking()
    {
        if (handbrakeInput > 0.1f)
        {
            ApplyBrakeTorque(RearLeftWheelCollider, brake * 1.5f * handbrakeInput);
            ApplyBrakeTorque(RearRightWheelCollider, brake * 1.5f * handbrakeInput);
        }
        else if (automaticGear)
        {
            if (brakeInput > 0.1f && !reverseGear)
            {
                ApplyBrakeTorque(FrontLeftWheelCollider, brake * brakeInput);
                ApplyBrakeTorque(FrontRightWheelCollider, brake * brakeInput);
                ApplyBrakeTorque(RearLeftWheelCollider, brake * brakeInput / 2f);
                ApplyBrakeTorque(RearRightWheelCollider, brake * brakeInput / 2f);
            }
            else if (brakeInput > 0.1f && reverseGear)
            {
                ApplyBrakeTorque(FrontLeftWheelCollider, 0f);
                ApplyBrakeTorque(FrontRightWheelCollider, 0f);
                ApplyBrakeTorque(RearLeftWheelCollider, 0f);
                ApplyBrakeTorque(RearRightWheelCollider, 0f);
            }
            else if (brakeInput < 0.1f)
            {
                ApplyBrakeTorque(FrontLeftWheelCollider, 0f);
                ApplyBrakeTorque(FrontRightWheelCollider, 0f);
                ApplyBrakeTorque(RearLeftWheelCollider, 0f);
                ApplyBrakeTorque(RearRightWheelCollider, 0f);
            }
        }
        else if (brakeInput > 0.1f && !reverseGear)
        {
            ApplyBrakeTorque(FrontLeftWheelCollider, brake * brakeInput);
            ApplyBrakeTorque(FrontRightWheelCollider, brake * brakeInput);
            ApplyBrakeTorque(RearLeftWheelCollider, brake * brakeInput / 2f);
            ApplyBrakeTorque(RearRightWheelCollider, brake * brakeInput / 2f);
        }
        else if (brakeInput > 0.1f && reverseGear)
        {
            ApplyBrakeTorque(FrontLeftWheelCollider, brake * brakeInput);
            ApplyBrakeTorque(FrontRightWheelCollider, brake * brakeInput);
            ApplyBrakeTorque(RearLeftWheelCollider, brake * brakeInput);
            ApplyBrakeTorque(RearRightWheelCollider, brake * brakeInput);
        }
        else if (brakeInput < 0.1f)
        {
            ApplyBrakeTorque(FrontLeftWheelCollider, 0f);
            ApplyBrakeTorque(FrontRightWheelCollider, 0f);
            ApplyBrakeTorque(RearLeftWheelCollider, 0f);
            ApplyBrakeTorque(RearRightWheelCollider, 0f);
        }
    }

    public void AntiRollBars()
    {
        float num = 1f;
        float num2 = 1f;
        WheelHit hit;
        bool groundHit = FrontLeftWheelCollider.GetGroundHit(out hit);
        if (groundHit)
        {
            Vector3 vector = FrontLeftWheelCollider.transform.InverseTransformPoint(hit.point);
            num = (0f - vector.y - FrontLeftWheelCollider.radius) / FrontLeftWheelCollider.suspensionDistance;
        }
        bool groundHit2 = FrontRightWheelCollider.GetGroundHit(out hit);
        if (groundHit2)
        {
            Vector3 vector2 = FrontRightWheelCollider.transform.InverseTransformPoint(hit.point);
            num2 = (0f - vector2.y - FrontRightWheelCollider.radius) / FrontRightWheelCollider.suspensionDistance;
        }
        float num3 = (num - num2) * antiRoll;
        if (groundHit)
        {
            rigid.AddForceAtPosition(FrontLeftWheelCollider.transform.up * (0f - num3), FrontLeftWheelCollider.transform.position);
        }
        if (groundHit2)
        {
            rigid.AddForceAtPosition(FrontRightWheelCollider.transform.up * num3, FrontRightWheelCollider.transform.position);
        }
        float num4 = 1f;
        float num5 = 1f;
        WheelHit hit2;
        bool groundHit3 = RearLeftWheelCollider.GetGroundHit(out hit2);
        if (groundHit3)
        {
            Vector3 vector3 = RearLeftWheelCollider.transform.InverseTransformPoint(hit2.point);
            num4 = (0f - vector3.y - RearLeftWheelCollider.radius) / RearLeftWheelCollider.suspensionDistance;
        }
        bool groundHit4 = RearRightWheelCollider.GetGroundHit(out hit2);
        if (groundHit4)
        {
            Vector3 vector4 = RearRightWheelCollider.transform.InverseTransformPoint(hit2.point);
            num5 = (0f - vector4.y - RearRightWheelCollider.radius) / RearRightWheelCollider.suspensionDistance;
        }
        float num6 = (num4 - num5) * antiRoll;
        if (groundHit3)
        {
            rigid.AddForceAtPosition(RearLeftWheelCollider.transform.up * (0f - num6), RearLeftWheelCollider.transform.position);
        }
        if (groundHit4)
        {
            rigid.AddForceAtPosition(RearRightWheelCollider.transform.up * num6, RearRightWheelCollider.transform.position);
        }
        if (groundHit4 && groundHit3 && AIController)
        {
            rigid.AddRelativeTorque(Vector3.up * (steerInput * gasInput) * 2000f);
        }
        if (_wheelTypeChoise == WheelType.DRIFT && groundHit4 && groundHit3)
        {
            rigid.AddRelativeTorque(Vector3.up * (steerInput * gasInput) * 5000f);
        }
    }

    public void DownForce()
    {
        rigid.AddForce(-base.transform.up * (downForce * rigid.velocity.magnitude));
    }

    public void SteerHelper()
    {
        for (int i = 0; i < allWheelColliders.Length; i++)
        {
            allWheelColliders[i].GetGroundHit(out WheelHit hit);
            if (hit.normal == Vector3.zero)
            {
                return;
            }
        }
        float num = oldRotation;
        Vector3 eulerAngles = base.transform.eulerAngles;
        if (Mathf.Abs(num - eulerAngles.y) < 10f)
        {
            Vector3 eulerAngles2 = base.transform.eulerAngles;
            float angle = (eulerAngles2.y - oldRotation) * steerHelper;
            Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.up);
            rigid.velocity = rotation * rigid.velocity;
        }
        Vector3 eulerAngles3 = base.transform.eulerAngles;
        oldRotation = eulerAngles3.y;
    }

    public void MobileSteeringInputs()
    {
        if (useAccelerometerForSteer)
        {
            Vector3 vector = Input.acceleration;
            steerInput = vector.x * gyroTiltMultiplier;
        }
        else if (steeringWheelControl)
        {
            steerInput = GetSteeringWheelInput();
        }
    }

    public void SteeringWheelControlling()
    {
        if (!steeringWheelCanvasGroup || !steeringWheelRect || !steeringWheelControl)
        {
            if ((bool)steeringWheelGameObject)
            {
                steeringWheelGameObject.SetActive(value: false);
            }
            return;
        }
        if (!steeringWheelGameObject.activeSelf)
        {
            steeringWheelGameObject.SetActive(value: true);
        }
        if (steeringWheelPressed)
        {
            if (steeringWheelInteractable)
            {
                steeringWheelCanvasGroup.alpha = steeringWheelActiveAlpha;
                steeringWheelNewAngle = Vector2.Angle(Vector2.up, steeringWheelTouchPos - steeringWheelCenter);
                if (Vector2.Distance(steeringWheelTouchPos, steeringWheelCenter) > steeringWheelCenterDeadZoneRadius)
                {
                    if (steeringWheelTouchPos.x > steeringWheelCenter.x)
                    {
                        steeringWheelAngle += steeringWheelNewAngle - steeringWheelTempAngle;
                    }
                    else
                    {
                        steeringWheelAngle -= steeringWheelNewAngle - steeringWheelTempAngle;
                    }
                }
                if (steeringWheelAngle > steeringWheelMaximumsteerAngle)
                {
                    steeringWheelAngle = steeringWheelMaximumsteerAngle;
                }
                else if (steeringWheelAngle < 0f - steeringWheelMaximumsteerAngle)
                {
                    steeringWheelAngle = 0f - steeringWheelMaximumsteerAngle;
                }
                steeringWheelTempAngle = steeringWheelNewAngle;
            }
        }
        else
        {
            steeringWheelCanvasGroup.alpha = steeringWheelDefaultAlpha;
            if (!Mathf.Approximately(0f, steeringWheelAngle))
            {
                float num = steeringWheelResetPosSpeed;
                if (Mathf.Abs(num) > Mathf.Abs(steeringWheelAngle))
                {
                    steeringWheelAngle = 0f;
                    return;
                }
                if (steeringWheelAngle > 0f)
                {
                    steeringWheelAngle -= num;
                }
                else
                {
                    steeringWheelAngle += num;
                }
            }
        }
        steeringWheelRect.eulerAngles = new Vector3(0f, 0f, 0f - steeringWheelAngle);
    }

    public void KeyboardControlling()
    {
        if (UnityEngine.Input.GetKeyDown(KeyCode.I))
        {
            KillOrStartEngine();
        }
        if (!changingGear)
        {
            gasInput = Mathf.Lerp(gasInput, Mathf.Clamp01(UnityEngine.Input.GetAxis("Vertical")), Time.deltaTime * 10f);
        }
        else
        {
            gasInput = Mathf.Lerp(gasInput, 0f, Time.deltaTime * 10f);
        }
        brakeInput = Mathf.Lerp(brakeInput, 0f - Mathf.Clamp(UnityEngine.Input.GetAxis("Vertical"), -1f, 0f), Time.deltaTime * 10f);
        handbrakeInput = UnityEngine.Input.GetAxis("Jump");
        if (Mathf.Abs(UnityEngine.Input.GetAxis("Horizontal")) > 0.05f)
        {
            steerInput = Mathf.Lerp(steerInput, UnityEngine.Input.GetAxis("Horizontal"), Time.deltaTime * 20f);
        }
        else
        {
            steerInput = Mathf.Lerp(steerInput, UnityEngine.Input.GetAxis("Horizontal"), Time.deltaTime * 20f);
        }
        if (Input.GetButton("Fire2"))
        {
            boostInput = 2.5f;
        }
        else
        {
            boostInput = 1f;
        }
    }

    public void NGUIControlling()
    {
        if (!changingGear)
        {
            gasInput = gasPedalNGUI.input;
        }
        else
        {
            gasInput = 0f;
        }
        brakeInput = brakePedalNGUI.input;
        if (!useAccelerometerForSteer && !steeringWheelControl)
        {
            steerInput = rightArrowNGUI.input + (0f - leftArrowNGUI.input);
        }
        if (handbrakeNGUI.input > 0.1f)
        {
            handbrakeInput = 1f;
        }
        else
        {
            handbrakeInput = 0f;
        }
        if ((bool)boostNGUI)
        {
            boostInput = Mathf.Clamp(boostNGUI.input * 2f, 1f, 2.5f);
        }
    }

    public void UIControlling()
    {
        if (!changingGear)
        {
            gasInput = gasPedalUI.input;
        }
        else
        {
            gasInput = 0f;
        }
        brakeInput = brakePedalUI.input;
        if (!useAccelerometerForSteer && !steeringWheelControl)
        {
            steerInput = rightArrowUI.input + (0f - leftArrowUI.input);
        }
        if (handbrakeUI.input > 0.1f)
        {
            handbrakeInput = 1f;
        }
        else if (handbrakeUI.input < 0.9f)
        {
            handbrakeInput = 0f;
        }
        if ((bool)boostUI)
        {
            boostInput = Mathf.Clamp(boostUI.input * 2f, 1f, 2.5f);
        }
    }

    public void GearBox()
    {
        if (speed <= gearSpeed[0])
        {
            if (handbrakeInput < 0.1f)
            {
                if (!reverseGear && automaticGear)
                {
                    clutchInput = Mathf.Lerp(clutchInput, Mathf.Lerp(1f, Mathf.Lerp(0.25f, 0f, wheelRPMToSpeed / gearSpeed[0]), gasInput), Time.deltaTime * 50f);
                }
                else if (automaticGear)
                {
                    clutchInput = Mathf.Lerp(clutchInput, Mathf.Lerp(1f, Mathf.Lerp(0.25f, 0f, wheelRPMToSpeed / gearSpeed[0]), brakeInput), Time.deltaTime * 50f);
                }
                else if (!automaticGear && !reverseGear)
                {
                    clutchInput = Mathf.Lerp(clutchInput, Mathf.Lerp(1f, Mathf.Lerp(0.25f, 0f, wheelRPMToSpeed / gearSpeed[0]), gasInput), Time.deltaTime * 50f);
                }
                else
                {
                    clutchInput = Mathf.Lerp(clutchInput, Mathf.Lerp(1f, Mathf.Lerp(0.25f, 0f, wheelRPMToSpeed / gearSpeed[0]), gasInput), Time.deltaTime * 50f);
                }
            }
            else
            {
                clutchInput = Mathf.Lerp(clutchInput, 1f, Time.deltaTime * 10f);
            }
        }
        else if (changingGear)
        {
            clutchInput = Mathf.Lerp(clutchInput, 1f, Time.deltaTime * 10f);
        }
        else
        {
            clutchInput = Mathf.Lerp(clutchInput, 0f, Time.deltaTime * 10f);
        }
        if (clutchInput > 1f)
        {
            clutchInput = 1f;
        }
        if (clutchInput < 0f)
        {
            clutchInput = 0f;
        }
        if (!AIController)
        {
            if (brakeInput > 0.1f)
            {
                Vector3 vector = base.transform.InverseTransformDirection(rigid.velocity);
                if (vector.z < 1f && canGoReverseNow && automaticGear && !changingGear && !reverseGear)
                {
                    StartCoroutine("ChangingGear", -1);
                    goto IL_030d;
                }
            }
            if (gasInput > 0.1f && reverseGear && !changingGear && automaticGear)
            {
                StartCoroutine("ChangingGear", 0);
            }
        }
        goto IL_030d;
    IL_030d:
        if (automaticGear)
        {
            if (currentGear < totalGears - 1 && !changingGear && !driftingNow && speed >= gearSpeed[currentGear] * 1.1f && FrontLeftWheelCollider.rpm > 0f)
            {
                StartCoroutine("ChangingGear", currentGear + 1);
            }
            if (currentGear > 0 && !changingGear && speed < gearSpeed[currentGear - 1] * 0.9f)
            {
                StartCoroutine("ChangingGear", currentGear - 1);
            }
            return;
        }
        if (currentGear < totalGears - 1 && !changingGear && Input.GetButtonDown("RCCShiftUp"))
        {
            if (!reverseGear)
            {
                StartCoroutine("ChangingGear", currentGear + 1);
            }
            else
            {
                StartCoroutine("ChangingGear", 0);
            }
        }
        if (currentGear >= 0 && Input.GetButtonDown("RCCShiftDown"))
        {
            StartCoroutine("ChangingGear", currentGear - 1);
        }
    }

    private IEnumerator ChangingGear(int gear)
    {
        changingGear = true;
        if (demoGUI)
        {
            MonoBehaviour.print("Shifted to: " + gear.ToString());
        }
        if (gearShiftingClips.Length > 0)
        {
            gearShiftingSound = RCCCreateAudioSource.NewAudioSource(base.gameObject, "Gear Shifting AudioSource", 5f, 5f, maxGearShiftingSoundVolume, gearShiftingClips[Random.Range(0, gearShiftingClips.Length)], loop: false, playNow: true, destroyAfterFinished: true);
        }
        yield return new WaitForSeconds(gearShiftingDelay);
        if (gear == -1)
        {
            currentGear = 0;
            reverseGear = true;
        }
        else
        {
            currentGear = gear;
            reverseGear = false;
        }
        changingGear = false;
    }

    public void WheelAlign(WheelCollider wc, Transform wm, float rotation)
    {
        Vector3 vector = wc.transform.TransformPoint(wc.center);
        wc.GetGroundHit(out WheelHit hit);
        Vector3 origin = vector;
        Vector3 direction = -wc.transform.up;
        float num = wc.suspensionDistance + wc.radius;
        Vector3 localScale = base.transform.localScale;
        RaycastHit hitInfo = default(RaycastHit);
        if (Physics.Raycast(origin, direction, out hitInfo, num * localScale.y) && !hitInfo.collider.isTrigger && hitInfo.transform.root != base.transform)
        {
            Transform transform = wm.transform;
            Vector3 point = hitInfo.point;
            Vector3 a = wc.transform.up * wc.radius;
            Vector3 localScale2 = base.transform.localScale;
            transform.position = point + a * localScale2.y;
            Vector3 vector2 = wc.transform.InverseTransformPoint(hit.point);
            float num2 = (0f - vector2.y - wc.radius) / wc.suspensionDistance;
            UnityEngine.Debug.DrawLine(hit.point, hit.point + wc.transform.up * (hit.force / rigid.mass), (!((double)num2 <= 0.0)) ? Color.white : Color.magenta);
            UnityEngine.Debug.DrawLine(hit.point, hit.point - wc.transform.forward * hit.forwardSlip * 2f, Color.green);
            UnityEngine.Debug.DrawLine(hit.point, hit.point - wc.transform.right * hit.sidewaysSlip * 2f, Color.red);
        }
        else
        {
            Transform transform2 = wm.transform;
            Vector3 a2 = vector;
            Vector3 a3 = wc.transform.up * wc.suspensionDistance;
            Vector3 localScale3 = base.transform.localScale;
            transform2.position = a2 - a3 * localScale3.y;
        }
        rotation += wc.rpm * 6f * Time.deltaTime;
        Transform transform3 = wm.transform;
        Quaternion rotation2 = wc.transform.rotation;
        float x = rotation;
        float y = wc.steerAngle;
        Quaternion rotation3 = wc.transform.rotation;
        transform3.rotation = rotation2 * Quaternion.Euler(x, y, rotation3.z);
    }

    private float WheelRotation(WheelCollider wc, float rotation)
    {
        rotation += wc.rpm * 6f * Time.deltaTime;
        return rotation;
    }

    public void WheelCamber(WheelCollider wc)
    {
        wc.GetGroundHit(out WheelHit hit);
        float num = Mathf.Lerp(-2f, 2f, hit.force / 7500f);
        Vector3 localPosition = wc.transform.localPosition;
        Vector3 euler = default(Vector3);
        if (localPosition.x < 0f)
        {
            Vector3 localEulerAngles = wc.transform.localEulerAngles;
            float x = localEulerAngles.x;
            Vector3 localEulerAngles2 = wc.transform.localEulerAngles;
            euler = new Vector3(x, localEulerAngles2.y, 0f - num);
        }
        else
        {
            Vector3 localEulerAngles3 = wc.transform.localEulerAngles;
            float x2 = localEulerAngles3.x;
            Vector3 localEulerAngles4 = wc.transform.localEulerAngles;
            euler = new Vector3(x2, localEulerAngles4.y, num);
        }
        Quaternion localRotation = Quaternion.Euler(euler);
        wc.transform.localRotation = localRotation;
    }

    public void Dashboard()
    {
        if (_dashboardType == DashboardType.NGUIDashboard)
        {
            if (!UIInputs)
            {
                UnityEngine.Debug.LogError("If you gonna use NGUI Dashboard, your NGUI Root must have ''RCCNGUIDashboardInputs''. First be sure your NGUI Root has ''RCCNGUIDashboardInputs.cs''.");
                dashBoard = false;
                return;
            }
            UIInputs.RPM = engineRPM;
            UIInputs.KMH = speed;
            UIInputs.Gear = ((!(FrontLeftWheelCollider.rpm > -10f)) ? (-1f) : ((float)currentGear));
            UIInputs.ABS = ABSAct;
            UIInputs.ESP = ESPAct;
            UIInputs.Park = ((handbrakeInput > 0.1f) ? true : false);
            UIInputs.Headlights = headLightsOn;
            RPMNeedleRotation = engineRPM / 50f;
            KMHNeedleRotation = speed / 360f * 470f;
            smoothedNeedleRotation = Mathf.Lerp(smoothedNeedleRotation, RPMNeedleRotation, Time.deltaTime * 5f);
            Transform transform = RPMNeedleNGUI.transform;
            Vector3 eulerAngles = RPMNeedleNGUI.transform.eulerAngles;
            float x = eulerAngles.x;
            Vector3 eulerAngles2 = RPMNeedleNGUI.transform.eulerAngles;
            transform.eulerAngles = new Vector3(x, eulerAngles2.y, 0f - smoothedNeedleRotation);
            Transform transform2 = KMHNeedleNGUI.transform;
            Vector3 eulerAngles3 = KMHNeedleNGUI.transform.eulerAngles;
            float x2 = eulerAngles3.x;
            Vector3 eulerAngles4 = KMHNeedleNGUI.transform.eulerAngles;
            transform2.eulerAngles = new Vector3(x2, eulerAngles4.y, 0f - KMHNeedleRotation);
        }
        if (_dashboardType != 0)
        {
            return;
        }
        if (!UIInputs)
        {
            UnityEngine.Debug.LogError("If you gonna use UI Dashboard, your Canvas Root must have ''RCCUIDashboardInputs''. First be sure your Canvas Root has ''RCCUIDashboardInputs.cs''.");
            dashBoard = false;
            return;
        }
        UIInputs.RPM = engineRPM;
        UIInputs.KMH = speed;
        UIInputs.Gear = ((!(FrontLeftWheelCollider.rpm > -10f)) ? (-1f) : ((float)currentGear));
        if (dashBoard && (bool)UIInputs)
        {
            UIInputs.NGear = changingGear;
        }
        UIInputs.ABS = ABSAct;
        UIInputs.ESP = ESPAct;
        UIInputs.Park = ((handbrakeInput > 0.1f) ? true : false);
        UIInputs.Headlights = headLightsOn;
        RPMNeedleRotation = engineRPM / 50f;
        KMHNeedleRotation = speed * 1.25f;
        smoothedNeedleRotation = Mathf.Lerp(smoothedNeedleRotation, RPMNeedleRotation, Time.deltaTime * 5f);
        Transform transform3 = RPMNeedle.transform;
        Vector3 eulerAngles5 = RPMNeedle.transform.eulerAngles;
        float x3 = eulerAngles5.x;
        Vector3 eulerAngles6 = RPMNeedle.transform.eulerAngles;
        transform3.eulerAngles = new Vector3(x3, eulerAngles6.y, 0f - smoothedNeedleRotation);
        Transform transform4 = KMHNeedle.transform;
        Vector3 eulerAngles7 = KMHNeedle.transform.eulerAngles;
        float x4 = eulerAngles7.x;
        Vector3 eulerAngles8 = KMHNeedle.transform.eulerAngles;
        transform4.eulerAngles = new Vector3(x4, eulerAngles8.y, 0f - KMHNeedleRotation);
    }

    public void SmokeWeedEveryday(GroundMaterial ground)
    {
        tireBurn = false;
        for (int i = 0; i < allWheelColliders.Length; i++)
        {
            allWheelColliders[i].GetGroundHit(out WheelHit hit);
            if (_wheelSlipAsphalt.Count > 0 && ground == GroundMaterial.Asphalt)
            {
                if (Mathf.Abs(hit.sidewaysSlip) > 0.25f || Mathf.Abs(hit.forwardSlip) > 0.35f)
                {
                    if (!_wheelSlipAsphalt[i].enableEmission && speed > 1f)
                    {
                        _wheelSlipAsphalt[i].enableEmission = true;
                    }
                    tireBurn = true;
                }
                else if (_wheelSlipAsphalt[i].enableEmission)
                {
                    _wheelSlipAsphalt[i].enableEmission = false;
                }
            }
            else if (_wheelSlipAsphalt.Count > 0 && _wheelSlipAsphalt[i].enableEmission)
            {
                _wheelSlipAsphalt[i].enableEmission = false;
            }
            if (_wheelSlipSand.Count > 0 && ground == GroundMaterial.Sand && hit.point != Vector3.zero)
            {
                if (Mathf.Abs(hit.sidewaysSlip) > 0.25f || Mathf.Abs(hit.forwardSlip) > 0.35f || speed > 20f)
                {
                    if (!_wheelSlipSand[i].enableEmission && speed > 1f)
                    {
                        _wheelSlipSand[i].enableEmission = true;
                    }
                    tireBurn = true;
                }
                else if (_wheelSlipSand[i].enableEmission)
                {
                    _wheelSlipSand[i].enableEmission = false;
                }
            }
            else if (_wheelSlipSand.Count > 0 && _wheelSlipSand[i].enableEmission)
            {
                _wheelSlipSand[i].enableEmission = false;
            }
        }
        if (exhaustGas.Length > 0 && engineRunning)
        {
            for (int j = 0; j < exhaustGas.Length; j++)
            {
                if (speed < 30f)
                {
                    if (!exhaustGas[j].enableEmission)
                    {
                        exhaustGas[j].enableEmission = true;
                    }
                    if (gasInput > 0.05f)
                    {
                        exhaustGas[j].emissionRate = 25f;
                        exhaustGas[j].startSpeed = 5f;
                        exhaustGas[j].startSize = 5f;
                    }
                    else
                    {
                        exhaustGas[j].emissionRate = 5f;
                        exhaustGas[j].startSpeed = 1f;
                        exhaustGas[j].startSize = 3f;
                    }
                }
                else if (exhaustGas[j].enableEmission)
                {
                    exhaustGas[j].enableEmission = false;
                }
            }
        }
        else
        {
            if (exhaustGas.Length <= 0)
            {
                return;
            }
            for (int k = 0; k < exhaustGas.Length; k++)
            {
                if (exhaustGas[k].enableEmission)
                {
                    exhaustGas[k].enableEmission = false;
                }
            }
        }
    }

    public void DriftVariables()
    {
        RearRightWheelCollider.GetGroundHit(out WheelHit hit);
        if (speed > 50f)
        {
            driftAngle = hit.sidewaysSlip / 1f;
        }
        else
        {
            driftAngle = 0f;
        }
        if (Mathf.Abs(hit.sidewaysSlip) > 0.25f)
        {
            driftingNow = true;
        }
        else
        {
            driftingNow = false;
        }
        if (_wheelTypeChoise == WheelType.DRIFT)
        {
            if (ESP)
            {
                UnityEngine.Debug.Log("ESP Is Disabled For Accurate Drifting For " + base.transform.name);
                ESP = false;
            }
            if (TCS)
            {
                UnityEngine.Debug.Log("TCS Is Disabled For Accurate Drifting For " + base.transform.name);
                TCS = false;
            }
            if (ABS)
            {
                UnityEngine.Debug.Log("ABS Is Disabled For Accurate Drifting For " + base.transform.name);
                ABS = false;
            }
            if (steeringHelper)
            {
                UnityEngine.Debug.Log("Steering Helper Is Disabled For Accurate Drifting For " + base.transform.name);
                steeringHelper = false;
            }
        }
    }

    public void GroundPhysicsMaterial()
    {
        if (sleepingRigid)
        {
            return;
        }
        RearLeftWheelCollider.GetGroundHit(out WheelHit hit);
        if (RearLeftWheelCollider.GetGroundHit(out hit))
        {
            if ((bool)asphaltPhysicsMaterial && hit.collider.material.name == asphaltPhysicsMaterial.name + " (Instance)")
            {
                _groundMaterial = GroundMaterial.Asphalt;
            }
            if ((bool)grassPhysicsMaterial && hit.collider.material.name == grassPhysicsMaterial.name + " (Instance)")
            {
                _groundMaterial = GroundMaterial.Grass;
            }
            if ((bool)sandPhysicsMaterial && hit.collider.material.name == sandPhysicsMaterial.name + " (Instance)")
            {
                _groundMaterial = GroundMaterial.Sand;
            }
            if (UseTerrainSplatMapForGroundPhysics)
            {
                if (hit.collider.material.name == terrainPhysicsMaterial.name + " (Instance)")
                {
                    if (TerrainSurface.GetTextureMix(RearLeftWheelCollider.transform.position)[terrainSplatMapAsphaltIndex] > 0.5f)
                    {
                        _groundMaterial = GroundMaterial.Asphalt;
                    }
                    else if (TerrainSurface.GetTextureMix(RearLeftWheelCollider.transform.position)[terrainSplatMapGrassIndex] > 0.5f)
                    {
                        _groundMaterial = GroundMaterial.Grass;
                    }
                    else if (TerrainSurface.GetTextureMix(RearLeftWheelCollider.transform.position)[terrainSplatMapSandIndex] > 0.5f)
                    {
                        _groundMaterial = GroundMaterial.Sand;
                    }
                    else
                    {
                        _groundMaterial = GroundMaterial.Asphalt;
                    }
                }
                else
                {
                    _groundMaterial = GroundMaterial.Asphalt;
                }
            }
            else
            {
                _groundMaterial = GroundMaterial.Asphalt;
            }
        }
        if (_groundMaterial == GroundMaterial.Asphalt)
        {
            SkidSound(asphaltSkidClip);
        }
        else if (_groundMaterial == GroundMaterial.Grass)
        {
            SkidSound(grassSkidClip);
        }
        else if (_groundMaterial == GroundMaterial.Sand)
        {
            SkidSound(sandSkidClip);
        }
    }

    public void SkidSound(AudioClip clip)
    {
        for (int i = 0; i < allWheelColliders.Length; i++)
        {
            allWheelColliders[i].GetGroundHit(out WheelHit hit);
            if (skidSound.clip != clip)
            {
                skidSound.clip = clip;
            }
            if (Mathf.Abs(hit.sidewaysSlip) > 0.25f || Mathf.Abs(hit.forwardSlip) > ((!(clip == sandSkidClip) && !(clip == grassSkidClip)) ? 0.35f : 0f))
            {
                if (rigid.velocity.magnitude > 1f)
                {
                    skidSound.volume = Mathf.Lerp(skidSound.volume, Mathf.Clamp(Mathf.Abs(hit.sidewaysSlip) + ((!(clip == sandSkidClip) && !(clip == grassSkidClip)) ? Mathf.Abs(hit.forwardSlip) : (speed / 100f)), 0f, maxSkidSoundVolume), Time.deltaTime * 30f);
                }
                else
                {
                    skidSound.volume -= Time.deltaTime * 1.5f;
                }
                if (!skidSound.isPlaying)
                {
                    skidSound.Play();
                }
            }
            else
            {
                skidSound.volume -= Time.deltaTime * 1.5f;
                if (skidSound.volume < 0.05f && skidSound.isPlaying)
                {
                    skidSound.Stop();
                }
            }
        }
    }

    public void ResetCar()
    {
        if (!(speed < 5f) || rigid.isKinematic)
        {
            return;
        }
        Vector3 eulerAngles = base.transform.eulerAngles;
        if (eulerAngles.z < 300f)
        {
            Vector3 eulerAngles2 = base.transform.eulerAngles;
            if (eulerAngles2.z > 60f)
            {
                resetTime += Time.deltaTime;
                if (resetTime > 3f)
                {
                    base.transform.rotation = Quaternion.identity;
                    Transform transform = base.transform;
                    Vector3 position = base.transform.position;
                    float x = position.x;
                    Vector3 position2 = base.transform.position;
                    float y = position2.y + 3f;
                    Vector3 position3 = base.transform.position;
                    transform.position = new Vector3(x, y, position3.z);
                    resetTime = 0f;
                }
            }
        }
        Vector3 eulerAngles3 = base.transform.eulerAngles;
        if (!(eulerAngles3.x < 300f))
        {
            return;
        }
        Vector3 eulerAngles4 = base.transform.eulerAngles;
        if (eulerAngles4.x > 60f)
        {
            resetTime += Time.deltaTime;
            if (resetTime > 3f)
            {
                base.transform.rotation = Quaternion.identity;
                Transform transform2 = base.transform;
                Vector3 position4 = base.transform.position;
                float x2 = position4.x;
                Vector3 position5 = base.transform.position;
                float y2 = position5.y + 3f;
                Vector3 position6 = base.transform.position;
                transform2.position = new Vector3(x2, y2, position6.z);
                resetTime = 0f;
            }
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.contacts.Length < 1 || collision.relativeVelocity.magnitude < minimumCollisionForce)
        {
            return;
        }
        if (crashClips.Length > 0 && collision.contacts[0].thisCollider.gameObject.transform != base.transform.parent)
        {
            crashSound = RCCCreateAudioSource.NewAudioSource(base.gameObject, "Crash Sound AudioSource", 5f, 20f, maxCrashSoundVolume, crashClips[Random.Range(0, crashClips.Length)], loop: false, playNow: true, destroyAfterFinished: true);
        }
        if (!useDamage)
        {
            return;
        }
        CollisionParticles(collision.contacts[0].point);
        Vector3 relativeVelocity = collision.relativeVelocity;
        relativeVelocity *= 1f - Mathf.Abs(Vector3.Dot(base.transform.up, collision.contacts[0].normal));
        float num = Mathf.Abs(Vector3.Dot(collision.contacts[0].normal, relativeVelocity.normalized));
        if (relativeVelocity.magnitude * num >= minimumCollisionForce)
        {
            sleep = false;
            localVector = base.transform.InverseTransformDirection(relativeVelocity) * (damageMultiplier / 50f);
            if (originalMeshData == null)
            {
                LoadOriginalMeshData();
            }
            for (int i = 0; i < deformableMeshFilters.Length; i++)
            {
                DeformMesh(deformableMeshFilters[i].mesh, originalMeshData[i].meshVerts, collision, num, deformableMeshFilters[i].transform, rot);
            }
        }
    }

    public void Chassis()
    {
        if (!sleepingRigid)
        {
            if (rigid.centerOfMass != base.transform.InverseTransformPoint(COM.transform.position))
            {
                rigid.centerOfMass = base.transform.InverseTransformPoint(COM.transform.position);
            }
            float a = verticalLean;
            Vector3 angularVelocity = rigid.angularVelocity;
            verticalLean = Mathf.Clamp(Mathf.Lerp(a, angularVelocity.x * chassisVerticalLean, Time.deltaTime * 3f), -3f, 3f);
            RearRightWheelCollider.GetGroundHit(out WheelHit hit);
            float num = Mathf.Clamp(hit.sidewaysSlip, -1f, 1f);
            num = ((!(num >= 0f)) ? (-1f) : 1f);
            Vector3 vector = base.transform.InverseTransformDirection(rigid.velocity);
            if (vector.z >= 0f)
            {
                float a2 = horizontalLean;
                Vector3 vector2 = base.transform.InverseTransformDirection(rigid.angularVelocity);
                horizontalLean = Mathf.Clamp(Mathf.Lerp(a2, vector2.y * chassisHorizontalLean, Time.deltaTime * 3f), -3f, 3f);
            }
            else
            {
                float a3 = horizontalLean;
                Vector3 vector3 = base.transform.InverseTransformDirection(rigid.angularVelocity);
                horizontalLean = Mathf.Clamp(Mathf.Lerp(a3, Mathf.Abs(vector3.y) * (0f - num) * chassisHorizontalLean, Time.deltaTime * 3f), -3f, 3f);
            }
            if (!float.IsNaN(verticalLean) && !float.IsNaN(horizontalLean) && !float.IsInfinity(verticalLean) && !float.IsInfinity(horizontalLean) && !Mathf.Approximately(verticalLean, 0f) && !Mathf.Approximately(horizontalLean, 0f))
            {
                float x = verticalLean;
                Quaternion localRotation = chassis.transform.localRotation;
                float y = localRotation.y;
                Vector3 angularVelocity2 = rigid.angularVelocity;
                Quaternion localRotation2 = Quaternion.Euler(x, y + angularVelocity2.z, horizontalLean);
                chassis.transform.localRotation = localRotation2;
            }
        }
    }

    public void Lights()
    {
        if (brakeInput > 0.1f)
        {
            brakeLightInput = Mathf.Lerp(brakeLightInput, 1f, Time.deltaTime * 50f);
        }
        else if (!headLightsOn)
        {
            brakeLightInput = Mathf.Lerp(brakeLightInput, 0f, Time.deltaTime * 50f);
        }
        else
        {
            brakeLightInput = Mathf.Lerp(brakeLightInput, 0.3f, Time.deltaTime * 50f);
        }
        if (UnityEngine.Input.GetKeyDown(KeyCode.L) && !AIController)
        {
            headLightsOn = !headLightsOn;
        }
        for (int i = 0; i < brakeLights.Length; i++)
        {
            if (!reverseGear)
            {
                brakeLights[i].intensity = brakeLightInput;
            }
            else if (!headLightsOn)
            {
                brakeLights[i].intensity = 0f;
            }
            else
            {
                brakeLights[i].intensity = Mathf.Lerp(brakeLights[i].intensity, 0.3f, Time.deltaTime * 50f);
            }
        }
        for (int j = 0; j < headLights.Length; j++)
        {
            if (headLightsOn)
            {
                headLights[j].enabled = true;
            }
            else
            {
                headLights[j].enabled = false;
            }
        }
        for (int k = 0; k < reverseLights.Length; k++)
        {
            if (!reverseGear)
            {
                reverseLights[k].intensity = Mathf.Lerp(reverseLights[k].intensity, 0f, Time.deltaTime * 50f);
            }
            else
            {
                reverseLights[k].intensity = brakeLightInput;
            }
        }
    }

    private void OnGUI()
    {
        if (demoGUI)
        {
            GUI.skin.label.fontSize = 12;
            GUI.skin.box.fontSize = 12;
            GUI.backgroundColor = Color.gray;
            float num = (float)Screen.width / 2f;
            GUI.Box(new Rect((float)(Screen.width - 400) - num, 10f, 800f, 270f), string.Empty);
            GUI.Label(new Rect((float)(Screen.width - 390) - num, 10f, 400f, 150f), "Engine RPM : " + Mathf.CeilToInt(engineRPM));
            GUI.Label(new Rect((float)(Screen.width - 200) - num, 10f, 400f, 150f), "Engine Running : " + ((!engineRunning) ? "Stopped" : "Running").ToString());
            GUI.Label(new Rect((float)(Screen.width - 200) - num, 30f, 400f, 150f), "Engine Starter : " + ((!engineStarting) ? "Stopped" : "Starting").ToString());
            GUI.Label(new Rect((float)(Screen.width - 200) - num, 90f, 400f, 150f), "Engine Sound On Volume: " + engineSoundOn.volume.ToString("F1"));
            GUI.Label(new Rect((float)(Screen.width - 200) - num, 110f, 400f, 150f), "Engine Sound On Pitch: " + engineSoundOn.pitch.ToString("F1"));
            GUI.Label(new Rect((float)(Screen.width - 200) - num, 130f, 400f, 150f), "Engine Sound Off Volume: " + engineSoundOff.volume.ToString("F1"));
            GUI.Label(new Rect((float)(Screen.width - 200) - num, 150f, 400f, 150f), "Engine Sound Off Pitch: " + engineSoundOff.pitch.ToString("F1"));
            GUI.Label(new Rect((float)(Screen.width - 390) - num, 30f, 400f, 150f), "Speed (KM/H) : " + Mathf.CeilToInt(speed));
            GUI.Label(new Rect((float)(Screen.width - 390) - num, 50f, 400f, 150f), "Steer Angle : " + Mathf.CeilToInt(FrontLeftWheelCollider.steerAngle));
            GUI.Label(new Rect((float)(Screen.width - 390) - num, 70f, 400f, 150f), "Automatic Shifting : " + ((!automaticGear) ? "Manual" : "Automatic").ToString());
            if (!changingGear)
            {
                GUI.Label(new Rect((float)(Screen.width - 390) - num, 90f, 400f, 150f), "Gear No : " + (reverseGear ? "R" : (currentGear + 1).ToString()).ToString());
            }
            else
            {
                GUI.Label(new Rect((float)(Screen.width - 390) - num, 90f, 400f, 150f), "Gear No : N");
            }
            Rect position = new Rect((float)(Screen.width - 390) - num, 230f, 400f, 150f);
            Vector3 vector = Input.acceleration;
            GUI.Label(position, "Mobile Horizontal Tilt : " + vector.x);
            Rect position2 = new Rect((float)(Screen.width - 390) - num, 250f, 400f, 150f);
            Vector3 vector2 = Input.acceleration;
            GUI.Label(position2, "Mobile Vertical Tilt : " + vector2.y);
            GUI.Label(new Rect((float)Screen.width - num, 10f, 400f, 150f), "Front Left Wheel RPM : " + Mathf.CeilToInt(FrontLeftWheelCollider.rpm));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 10f, 400f, 150f), "Front Right Wheel RPM : " + Mathf.CeilToInt(FrontRightWheelCollider.rpm));
            GUI.Label(new Rect((float)Screen.width - num, 30f, 400f, 150f), "Front Left Wheel Torque : " + Mathf.CeilToInt(FrontLeftWheelCollider.motorTorque));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 30f, 400f, 150f), "Front Right Wheel Torque : " + Mathf.CeilToInt(FrontRightWheelCollider.motorTorque));
            GUI.Label(new Rect((float)Screen.width - num, 50f, 400f, 150f), "Front Left Wheel brake : " + Mathf.CeilToInt(FrontLeftWheelCollider.brakeTorque));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 50f, 400f, 150f), "Front Right Wheel brake : " + Mathf.CeilToInt(FrontRightWheelCollider.brakeTorque));
            FrontLeftWheelCollider.GetGroundHit(out WheelHit hit);
            GUI.Label(new Rect((float)(Screen.width - 200) - num, 190f, 400f, 150f), "Speed: " + speed);
            GUI.Label(new Rect((float)(Screen.width - 200) - num, 210f, 400f, 150f), "WCSpeed: " + wheelRPMToSpeed);
            if (FrontLeftWheelCollider.GetGroundHit(out hit))
            {
                GUI.Label(new Rect((float)(Screen.width - 200) - num, 50f, 400f, 150f), "Ground Material : " + _groundMaterial.ToString());
                GUI.Label(new Rect((float)(Screen.width - 200) - num, 70f, 400f, 150f), "Ground Grip : " + FrontLeftWheelCollider.forwardFriction.stiffness);
            }
            GUI.Label(new Rect((float)Screen.width - num, 70f, 400f, 150f), "Front Left Wheel Force : " + Mathf.CeilToInt(hit.force));
            GUI.Label(new Rect((float)Screen.width - num, 90f, 400f, 150f), "Front Left Wheel Sideways Grip : " + (1f - Mathf.Abs(hit.sidewaysSlip)).ToString("F2"));
            GUI.Label(new Rect((float)Screen.width - num, 110f, 400f, 150f), "Front Left Wheel Forward Grip : " + (1f - Mathf.Abs(hit.forwardSlip)).ToString("F2"));
            FrontRightWheelCollider.GetGroundHit(out hit);
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 70f, 400f, 150f), "Front Right Wheel Force : " + Mathf.CeilToInt(hit.force));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 90f, 400f, 150f), "Front Right Wheel Sideways Grip : " + (1f - Mathf.Abs(hit.sidewaysSlip)).ToString("F2"));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 110f, 400f, 150f), "Front Right Wheel Forward Grip : " + (1f - Mathf.Abs(hit.forwardSlip)).ToString("F2"));
            GUI.Label(new Rect((float)(Screen.width - 390) - num, 170f, 400f, 150f), "ABS: " + ABS + ". Current State: " + ((!ABSAct) ? "Safe" : "Engaged").ToString());
            GUI.Label(new Rect((float)(Screen.width - 390) - num, 190f, 400f, 150f), "TCS: " + TCS + ". Current State: " + ((!TCSAct) ? "Safe" : "Engaged").ToString());
            GUI.Label(new Rect((float)(Screen.width - 390) - num, 210f, 400f, 150f), "ESP: " + ESP + ". Current State: " + ((!ESPAct) ? "Safe" : "Engaged").ToString());
            GUI.Label(new Rect((float)Screen.width - num, 150f, 400f, 150f), "Rear Left Wheel RPM : " + Mathf.CeilToInt(RearLeftWheelCollider.rpm));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 150f, 400f, 150f), "Rear Right Wheel RPM : " + Mathf.CeilToInt(RearRightWheelCollider.rpm));
            GUI.Label(new Rect((float)Screen.width - num, 170f, 400f, 150f), "Rear Left Wheel Torque : " + Mathf.CeilToInt(RearLeftWheelCollider.motorTorque));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 170f, 400f, 150f), "Rear Right Wheel Torque : " + Mathf.CeilToInt(RearRightWheelCollider.motorTorque));
            GUI.Label(new Rect((float)Screen.width - num, 190f, 400f, 150f), "Rear Left Wheel brake : " + Mathf.CeilToInt(RearLeftWheelCollider.brakeTorque));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 190f, 400f, 150f), "Rear Right Wheel brake : " + Mathf.CeilToInt(RearRightWheelCollider.brakeTorque));
            RearLeftWheelCollider.GetGroundHit(out hit);
            GUI.Label(new Rect((float)Screen.width - num, 210f, 400f, 150f), "Rear Left Wheel Force : " + Mathf.CeilToInt(hit.force));
            GUI.Label(new Rect((float)Screen.width - num, 230f, 400f, 150f), "Rear Left Wheel Sideways Grip : " + (1f - Mathf.Abs(hit.sidewaysSlip)).ToString("F2"));
            GUI.Label(new Rect((float)Screen.width - num, 250f, 400f, 150f), "Rear Left Wheel Forward Grip : " + (1f - Mathf.Abs(hit.forwardSlip)).ToString("F2"));
            RearRightWheelCollider.GetGroundHit(out hit);
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 210f, 400f, 150f), "Rear Right Wheel Force : " + Mathf.CeilToInt(hit.force));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 230f, 400f, 150f), "Rear Right Wheel Sideways Grip : " + (1f - Mathf.Abs(hit.sidewaysSlip)).ToString("F2"));
            GUI.Label(new Rect((float)(Screen.width + 200) - num, 250f, 400f, 150f), "Rear Right Wheel Forward Grip : " + (1f - Mathf.Abs(hit.forwardSlip)).ToString("F2"));
            GUI.backgroundColor = Color.green;
            GUI.Button(new Rect((float)(Screen.width - 20) - num, 260f, 10f, Mathf.Clamp((0f - gasInput) * 100f, -100f, 0f)), string.Empty);
            GUI.backgroundColor = Color.red;
            GUI.Button(new Rect((float)(Screen.width - 35) - num, 260f, 10f, Mathf.Clamp((0f - brakeInput) * 100f, -100f, 0f)), string.Empty);
            GUI.backgroundColor = Color.blue;
            GUI.Button(new Rect((float)(Screen.width - 50) - num, 260f, 10f, Mathf.Clamp((0f - clutchInput) * 100f, -100f, 0f)), string.Empty);
        }
        if (!canControl)
        {
            return;
        }
        if (useAccelerometerForSteer && mobileController)
        {
            if (_mobileControllerType == MobileGUIType.NGUIController)
            {
                if ((bool)leftArrowNGUI && leftArrowNGUI.gameObject.activeSelf)
                {
                    leftArrowNGUI.gameObject.SetActive(value: false);
                }
                if ((bool)rightArrowNGUI && rightArrowNGUI.gameObject.activeSelf)
                {
                    rightArrowNGUI.gameObject.SetActive(value: false);
                }
                if ((bool)handbrakeNGUI && !handbrakeNGUI.gameObject.activeSelf)
                {
                    handbrakeNGUI.gameObject.SetActive(value: true);
                }
                if ((bool)brakePedalNGUI)
                {
                    brakePedalNGUI.transform.position = leftArrowNGUI.transform.position;
                }
            }
            if (_mobileControllerType == MobileGUIType.UIController)
            {
                if ((bool)leftArrowUI && leftArrowUI.gameObject.activeSelf)
                {
                    leftArrowUI.gameObject.SetActive(value: false);
                }
                if ((bool)rightArrowUI && rightArrowUI.gameObject.activeSelf)
                {
                    rightArrowUI.gameObject.SetActive(value: false);
                }
                if ((bool)handbrakeUI && !handbrakeUI.gameObject.activeSelf)
                {
                    handbrakeUI.gameObject.SetActive(value: true);
                }
                if ((bool)brakePedalUI)
                {
                    brakePedalUI.transform.position = leftArrowUI.transform.position;
                }
            }
            steeringWheelControl = false;
        }
        else if (mobileController)
        {
            if (_mobileControllerType == MobileGUIType.NGUIController)
            {
                if ((bool)gasPedalNGUI && !gasPedalNGUI.gameObject.activeSelf)
                {
                    gasPedalNGUI.gameObject.SetActive(value: true);
                }
                if ((bool)brakePedalNGUI && !brakePedalNGUI.gameObject.activeSelf)
                {
                    brakePedalNGUI.gameObject.SetActive(value: true);
                }
                if ((bool)leftArrowNGUI && !leftArrowNGUI.gameObject.activeSelf)
                {
                    leftArrowNGUI.gameObject.SetActive(value: true);
                }
                if ((bool)rightArrowNGUI && !rightArrowNGUI.gameObject.activeSelf)
                {
                    rightArrowNGUI.gameObject.SetActive(value: true);
                }
                if ((bool)handbrakeNGUI && !handbrakeNGUI.gameObject.activeSelf)
                {
                    handbrakeNGUI.gameObject.SetActive(value: true);
                }
                if ((bool)brakePedalNGUI)
                {
                    brakePedalNGUI.transform.position = defbrakePedalPosition;
                }
            }
            if (_mobileControllerType == MobileGUIType.UIController)
            {
                if ((bool)gasPedalUI && !gasPedalUI.gameObject.activeSelf)
                {
                    gasPedalUI.gameObject.SetActive(value: true);
                }
                if ((bool)brakePedalUI && !brakePedalUI.gameObject.activeSelf)
                {
                    brakePedalUI.gameObject.SetActive(value: true);
                }
                if ((bool)leftArrowUI && !leftArrowUI.gameObject.activeSelf)
                {
                    leftArrowUI.gameObject.SetActive(value: true);
                }
                if ((bool)rightArrowUI && !rightArrowUI.gameObject.activeSelf)
                {
                    rightArrowUI.gameObject.SetActive(value: true);
                }
                if ((bool)handbrakeUI && !handbrakeUI.gameObject.activeSelf)
                {
                    handbrakeUI.gameObject.SetActive(value: true);
                }
                if ((bool)brakePedalUI)
                {
                    brakePedalUI.transform.position = defbrakePedalPosition;
                }
            }
        }
        if (steeringWheelControl && mobileController)
        {
            if (_mobileControllerType == MobileGUIType.NGUIController)
            {
                if ((bool)leftArrowNGUI && leftArrowNGUI.gameObject.activeSelf)
                {
                    leftArrowNGUI.gameObject.SetActive(value: false);
                }
                if ((bool)rightArrowNGUI && rightArrowNGUI.gameObject.activeSelf)
                {
                    rightArrowNGUI.gameObject.SetActive(value: false);
                }
            }
            if (_mobileControllerType == MobileGUIType.UIController)
            {
                if ((bool)leftArrowUI && leftArrowUI.gameObject.activeSelf)
                {
                    leftArrowUI.gameObject.SetActive(value: false);
                }
                if ((bool)rightArrowUI && rightArrowUI.gameObject.activeSelf)
                {
                    rightArrowUI.gameObject.SetActive(value: false);
                }
            }
        }
        if (showMobileControllerChangerButtons && canControl)
        {
            if (GUI.Button(new Rect(Screen.width - 275, Screen.height / 2 - 35, 250f, 50f), "Use Accelerometer \n For Steer"))
            {
                useAccelerometerForSteer = !useAccelerometerForSteer;
            }
            if (GUI.Button(new Rect(Screen.width - 275, Screen.height / 2 + 35, 250f, 50f), "Use Steering Wheel \n For Steer"))
            {
                steeringWheelControl = !steeringWheelControl;
            }
        }
    }

    private bool OverTorque()
    {
        if (speed > maxspeed || !engineRunning)
        {
            return true;
        }
        if (reverseGear && speed > 55f)
        {
            return true;
        }
        if (!engineRunning)
        {
            return true;
        }
        return false;
    }

    private void OnDrawGizmos()
    {
    }

    private void SteeringWheelEventsInit()
    {
        eventTrigger = steeringWheelGameObject.GetComponent<EventTrigger>();
        EventTrigger.TriggerEvent triggerEvent = new EventTrigger.TriggerEvent();
        triggerEvent.AddListener(delegate (BaseEventData data)
        {
            PointerEventData pointerEventData2 = (PointerEventData)data;
            data.Use();
            steeringWheelPressed = true;
            steeringWheelTouchPos = pointerEventData2.position;
            steeringWheelTempAngle = Vector2.Angle(Vector2.up, pointerEventData2.position - steeringWheelCenter);
        });
        eventTrigger.triggers.Add(new EventTrigger.Entry
        {
            callback = triggerEvent,
            eventID = EventTriggerType.PointerDown
        });
        EventTrigger.TriggerEvent triggerEvent2 = new EventTrigger.TriggerEvent();
        triggerEvent2.AddListener(delegate (BaseEventData data)
        {
            PointerEventData pointerEventData = (PointerEventData)data;
            data.Use();
            steeringWheelTouchPos = pointerEventData.position;
        });
        eventTrigger.triggers.Add(new EventTrigger.Entry
        {
            callback = triggerEvent2,
            eventID = EventTriggerType.Drag
        });
        EventTrigger.TriggerEvent triggerEvent3 = new EventTrigger.TriggerEvent();
        triggerEvent3.AddListener(delegate
        {
            steeringWheelPressed = false;
        });
        eventTrigger.triggers.Add(new EventTrigger.Entry
        {
            callback = triggerEvent3,
            eventID = EventTriggerType.EndDrag
        });
    }

    public float GetSteeringWheelInput()
    {
        return Mathf.Round(steeringWheelAngle / steeringWheelMaximumsteerAngle * 100f) / 100f;
    }

    public bool isSteeringWheelPressed()
    {
        return steeringWheelPressed;
    }
}
